<template>
  <div>
    <input ref="fileInput" type="file" @change="handleFileChange"/>
    <button @click="uploadFile">Upload File</button>

    <!-- 显示上传进度 -->
    <progress v-if="uploading" :value="progress" max="100"></progress>
    <div v-if="uploading">上传进度: {{ progress }}%</div>
  </div>
</template>

<script>
import SparkMD5 from 'spark-md5';
import request from "@/utils/request";

export default {
  data() {
    return {
      file: null,
      fileHash: '',
      chunkSize: 5 * 1024 * 1024, // 5MB per chunk
      progress: 0, // 上传进度
      uploading: false, // 上传状态
    };
  },
  methods: {
    // 选择文件并计算文件MD5
    handleFileChange(event) {
      this.file = event.target.files[0];
      if (this.file) {
        this.calculateFileMD5(this.file);
      }
    },

    // 使用 SparkMD5 计算文件哈希值
    calculateFileMD5(file) {
      const reader = new FileReader();
      reader.onload = () => {
        const spark = new SparkMD5.ArrayBuffer();
        spark.append(reader.result);
        this.fileHash = spark.end();  // 获取文件哈希值
      };
      reader.readAsArrayBuffer(file);
    },

    // 上传文件的主方法
    async uploadFile() {
      this.uploading = true;  // 开始上传
      this.progress = 0;  // 重置进度

      // 验证文件是否已经上传（秒传）
      const verifyResponse = await request({
        url: '/upload/verify',
        method: 'post',
        params: { fileHash: this.fileHash },
      });

      if (verifyResponse === 'File already uploaded!') {
        alert('File already uploaded!');
        this.uploading = false;
        return;
      }

      // 分片上传
      const totalChunks = Math.ceil(this.file.size / this.chunkSize);
      for (let i = 0; i < totalChunks; i++) {
        const chunk = this.file.slice(i * this.chunkSize, (i + 1) * this.chunkSize);
        const formData = new FormData();
        formData.append('file', chunk);
        formData.append('fileHash', this.fileHash);
        formData.append('chunkIndex', i);
        formData.append('totalChunks', totalChunks);

        // 上传分片
        await this.uploadChunk(formData, i, totalChunks);
      }

      // 合并文件分片
      const mergeResponse = await request({
        url: '/upload/merge',
        method: 'post',
        params: {
          fileHash: this.fileHash,
          totalChunks,
        },
      });

      if (mergeResponse === 'File merged successfully') {
        alert('File uploaded successfully');
      } else {
        alert('Error merging chunks');
      }

      this.uploading = false;  // 上传完成
    },

    // 上传单个分片并更新进度
    async uploadChunk(formData, chunkIndex, totalChunks) {
      try {
        const response = await request({
          url: '/upload/chunk',
          method: 'post',
          data: formData,
          headers: {
            'Content-Type': 'multipart/form-data',
          },
          onUploadProgress: (progressEvent) => {
            if (progressEvent.total) {
              // 计算每个分片上传进度并更新总进度
              const chunkProgress = Math.round((chunkIndex + (progressEvent.loaded / progressEvent.total)) / totalChunks * 100);
              this.progress = chunkProgress;
            }
          },
        });

        console.log('Uploaded chunk:', response);

      } catch (error) {
        console.error('Error uploading chunk:', error);
        this.uploading = false;
      }
    },
  },
};
</script>

<style scoped>
progress {
  width: 100%;
  height: 20px;
}

div {
  margin-top: 20px;
}
</style>
